#include "DX2DRender.h"
#include "Console.h"
#include <algorithm>
#include <iostream>
#include <fstream>

namespace ConsoleDebug
{
	static const int g_czBufferSize = 4096;

	static char g_czBuffer[g_czBufferSize];

	static DXConsoleBase* g_pConsole = NULL;

	static bool g_bRecordLog = true;

	static std::string g_strLogMessage = "";
	
	
	#define _APPEND_FILE_LOG(x)						\
		if(g_bRecordLog)							\
		{											\
			g_strLogMessage += x;					\
			g_strLogMessage += "\n";				\
		}
	void AddLog(const char* x)
	{
		_APPEND_FILE_LOG(x)
	}
	void _SetIsRecordLog(bool bLog)
	{
		g_bRecordLog = bLog;
	}

	bool _GetIsRecordLog(void)
	{
		return g_bRecordLog;
	}

	void _WriteLog(const char* filename)
	{
		std::ofstream myfile;
		myfile.open (filename);
		myfile << g_strLogMessage;
		myfile.close();
	}

	void _Initialize(HWND owner, IDirect3DDevice9*  pd3dDevice, int w, int h)
	{
		if(!g_pConsole)
			g_pConsole = new DXConsole();
		g_pConsole->Initialize( owner, pd3dDevice, w, h);

	}

	void _ConsoleOutput(int nFlag, const char *vFormat ,...)
	{
		va_list   vArg;   
		va_start(vArg,vFormat);  
		vsprintf_s(g_czBuffer,g_czBufferSize,vFormat,vArg);
		if(!g_pConsole)
		{
			OutputDebugString(g_czBuffer);
		}
		else
		{
			g_pConsole->Output(g_czBuffer,nFlag);
		}

		_APPEND_FILE_LOG(g_czBuffer);

		va_end(vArg);   
	}

	void _ConsoleStdout(const char* szBuffer)
	{	
		if(!g_pConsole)
		{
			OutputDebugString(szBuffer);
		}
		else
		{
			g_pConsole->Output(szBuffer,ConsoleDebug_OUTPUT_STDOUT);
		}
		_APPEND_FILE_LOG(szBuffer);

	}

	void _ConsoleStderr(const char* szBuffer)
	{
		if(!g_pConsole)
		{
			OutputDebugString(szBuffer);
		}
		else
		{
			g_pConsole->Output(szBuffer,ConsoleDebug_OUTPUT_STDERR);
		}

		_APPEND_FILE_LOG(szBuffer);
	
	}

	void _ConsoleInput(const char* szBuffer)
	{
		if(!g_pConsole)
			return;
		if(g_pConsole->Active())
		{
			g_pConsole->InputString(std::string(szBuffer));
		}
		
	}

	void _ConsoleClear(void)
	{
		if(!g_pConsole)
			return;
		g_pConsole->ClearOutput();
	}


	void _SetOnEnterCallback(ConsoleCallbackEnter val)
	{
		if(!g_pConsole)
			return;
		g_pConsole->OnEnterCallback(val);
	}

	bool _OnInput(UINT message, WPARAM wParam, LPARAM lParam)
	{
		if(!g_pConsole)
			return false;
		return g_pConsole->OnInput(message,wParam,lParam);

		return false;
	}
	
	void _Render(IDirect3DDevice9*  pd3dDevice, float ftime)
	{
		if(!g_pConsole)
			return ;

		if(g_pConsole->Active())
		{
			g_pConsole->Render(pd3dDevice,ftime);
		}
	}

	void _Kill(void)
	{
		if(g_pConsole)
			delete g_pConsole;

		g_pConsole = NULL;
	}

	void _OnResetDevice(void)
	{
		if(!g_pConsole)
			return;

		g_pConsole->OnLostDevice();
	}

	void _OnLostDevice(void)
	{
		if(!g_pConsole)
			return;

		g_pConsole->OnResetDevice();
	}

	void _SetOnTabCallback(ConsoleCallbackTab v)
	{
		if(!g_pConsole)
			return;
		g_pConsole->OnTabCallback(v);
	}


	void _SetAcceptInput(bool b)
	{
		if(g_pConsole)
		{
			g_pConsole->AcceptInput(b);
		}
	}

	bool _GetAcceptInput(void)
	{
		if(g_pConsole)
		{
			return g_pConsole->AcceptInput();
		}
		return false;
	}

	void _SetActive(bool b)
	{
		if(g_pConsole)
		{
			g_pConsole->Active(b);
		}
	}

	bool _GetActive(void)
	{
		if(g_pConsole)
		{
			return g_pConsole->Active();
		}
		else
		{
			return false;
		}
	}

	void _SetHotKey(int op, int main, int mod )
	{
		if(g_pConsole)
		{
			g_pConsole->SetHotKey(op,main,mod);
		}
	}

	void _SetHAnchor(int x)
	{
		if(g_pConsole)
		{
			g_pConsole->SetHAnchor(x);
		}
	}

	void _SetScrollType(int x)
	{
		if(g_pConsole)
		{
			g_pConsole->SetScrollType(x);
		}
	}

	void _SetMaxDisplayLines(int x)
	{
		if(g_pConsole)
		{
			g_pConsole->MaxDisplayLines(x);
		}
	}

	void _SetShowBackground(bool x)
	{
		if(g_pConsole)
		{
			g_pConsole->ShowBackground(x);
		}
	}

	bool _IsInit(void)
	{
		if(g_pConsole)
		{
			return g_pConsole->IsInit();
		}
		return false;
	}
};